<?php

declare(strict_types=1);

namespace App\Admin;

use App\Entity\AdminUserGroup;
use App\Form\Type\ModuleFieldType;
use App\Utils\Helper\GeneralHelper;
use App\Utils\Helper\GetterHelper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\AdminBundle\Show\ShowMapper;

final class AdminUserGroupAdmin extends AbstractAdmin
{

    protected $baseRouteName = 'admin_adminusergroup';
    protected $baseRoutePattern = 'adminusergroup';

    protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
    {
        $datagridMapper
            ->add('name', null, ['label' => '名称']);
    }

    protected function configureListFields(ListMapper $listMapper): void
    {
        $listMapper
            ->addIdentifier('name', null, ['label' => '名称'])
            ->add('created_at', null, [
                'format' => 'Y-m-d H:i:s',
                'timezone' => 'PRC',
                'label' => '创建时间'
            ]);
    }

    protected function configureFormFields(FormMapper $formMapper): void
    {
        $formMapper
            ->add('name', null, ['label' => '名称'])
            ->add('module', ModuleFieldType::class, ['label' => '模块']);
    }

    protected function configureShowFields(ShowMapper $showMapper): void
    {
        $showMapper
            ->add('id')
            ->add('name')
            ->add('module_ids')
            ->add('created_at')
            ->add('updated_at');
    }

    public function prePersist($object)
    {
        parent::prePersist($object); // TODO: Change the autogenerated stub

        $object->setCreatedAt(new \DateTime());
        // 保存参数
        $this->saveModuleIds($object);
    }

    public function preUpdate($object)
    {
        parent::preUpdate($object); // TODO: Change the autogenerated stub

        // 保存参数
        $this->saveModuleIds($object);
    }

    public function postUpdate($object)
    {
        parent::postUpdate($object); // TODO: Change the autogenerated stub

        // 同步更新用户组可访问模块集合缓存
        GetterHelper::getEntityManager()->getRepository(AdminUserGroup::class)->getAdminModuleByAdminUserGroup($object, true);
        // 同步更新用户组可访问模块sonata_admin集合缓存
        GetterHelper::getEntityManager()->getRepository(AdminUserGroup::class)->getSonataAdminById($object->getId(), true);
    }

    private function saveModuleIds($object)
    {
        $module_ids = $this->getRequest()->get('module_idx', []);
        $ids = [];
        foreach ($module_ids as $pid => $_ids) {
            array_push($ids, $pid);
            $ids = array_merge($ids, $_ids);
        }
        $ids = array_map(function ($value) {
            return (int)$value;
        }, $ids);
        $object->setModuleIds(json_encode($ids));
    }

    public function preRemove($object)
    {
        parent::preRemove($object); // TODO: Change the autogenerated stub

        $this->verifyDelete([$object->getId()], 'edit');
    }

    public function preBatchAction($actionName, ProxyQueryInterface $query, array &$idx, $allElements)
    {
        switch ($actionName) {
            case 'delete':
                $this->verifyDelete($idx, 'list', $allElements);
                break;
        }

        parent::preBatchAction($actionName, $query, $idx, $allElements); // TODO: Change the autogenerated stub
    }

    private function verifyDelete($ids = [], $action = 'list', $allElements = false)
    {
        // 如果有用户关联则不能删除
        $admin_user_count = GetterHelper::getEntityManager()->getRepository(AdminUserGroup::class)->getAdminUserCount($ids);
        if ($admin_user_count > 0 || $allElements) {
            $message = '批量处理的用户组中有用户关联，不能删除';
            $url = $this->generateUrl('list', $this->getFilterParameters());
            switch ($action) {
                case 'list':
                    break;
                case 'edit':
                    $message = '该用户组有用户关联，不能删除';
                    $url = $this->generateObjectUrl('edit', $this->getSubject());
                    break;
            }
            GeneralHelper::getOneInstance()->addFlash('sonata_flash_error', $message);
            header("Location:" . $url);
            exit();
        }
    }

    protected function configureRoutes(RouteCollection $collection)
    {
        parent::configureRoutes($collection); // TODO: Change the autogenerated stub

        $collection->remove('export');
        $collection->remove('show');
    }
}
